﻿using System;
using System.Security;
using System.Security.AccessControl;
using System.Security.Principal;
using System.IO;
using System.Text;

namespace PSE.Framework.UI.Controls.SmartClient
{
	public class FileAccessRigths
	{
        string _path;
        bool _denyAppendData = false;
        bool _denyChangePermissions = false;
        bool _denyCreateDirectories = false;
        bool _denyCreateFiles = false;
        bool _denyDelete = false;
        bool _denyDeleteSubdirectoriesAndFiles = false;
        bool _denyExecuteFile = false;
        bool _denyFullControl = false;
        bool _denyListDirectory = false;
        bool _denyModify = false;
        bool _denyRead = false;
        bool _denyReadAndExecute = false;
        bool _denyReadAttributes = false;
        bool _denyReadData = false;
        bool _denyReadExtendedAttributes = false;
        bool _denyReadPermissions = false;
        bool _denySynchronize = false;
        bool _denyTakeOwnership = false;
        bool _denyTraverse = false;
        bool _denyWrite = false;
        bool _denyWriteAttributes = false;
        bool _denyWriteData = false;
        bool _denyWriteExtendedAttributes = false;
        bool _allowAppendData = false;
        bool _allowChangePermissions = false;
        bool _allowCreateDirectories = false;
        bool _allowCreateFiles = false;
        bool _allowDelete = false;
        bool _allowDeleteSubdirectoriesAndFiles = false;
        bool _allowExecuteFile = false;
        bool _allowFullControl = false;
        bool _allowListDirectory = false;
        bool _allowModify = false;
        bool _allowRead = false;
        bool _allowReadAndExecute = false;
        bool _allowReadAttributes = false;
        bool _allowReadData = false;
        bool _allowReadExtendedAttributes = false;
        bool _allowReadPermissions = false;
        bool _allowSynchronize = false;
        bool _allowTakeOwnership = false;
        bool _allowTraverse = false;
        bool _allowWrite = false;
        bool _allowWriteAttributes = false;
        bool _allowWriteData = false;
        bool _allowWriteExtendedAttributes = false;

        public bool CanAppendData
        {
            get { return !_denyAppendData && _allowAppendData; }
        }
        public bool CanChangePermissions
        {
            get { return !_denyChangePermissions && _allowChangePermissions; }
        }
        public bool CanCreateDirectories
        {
            get { return !_denyCreateDirectories && _allowCreateDirectories; }
        }
        public bool CanCreateFiles
        {
            get { return !_denyCreateFiles && _allowCreateFiles; }
        }
        public bool CanDelete
        {
            get { return !_denyDelete && _allowDelete; }
        }
        public bool CanDeleteSubdirectoriesAndFiles
        {
            get { return !_denyDeleteSubdirectoriesAndFiles && _allowDeleteSubdirectoriesAndFiles; }
        }
        public bool CanExecuteFile
        {
            get { return !_denyExecuteFile && _allowExecuteFile; }
        }
        public bool CanFullControl
        {
            get { return !_denyFullControl && _allowFullControl; }
        }
        public bool CanListDirectory
        {
            get { return !_denyListDirectory && _allowListDirectory; }
        }
        public bool CanModify
        {
            get { return !_denyModify && _allowModify; }
        }
        public bool CanRead
        {
            get { return !_denyRead && _allowRead; }
        }
        public bool CanReadAndExecute
        {
            get { return !_denyReadAndExecute && _allowReadAndExecute; }
        }
        public bool CanReadAttributes
        {
            get { return !_denyReadAttributes && _allowReadAttributes; }
        }
        public bool CanReadData
        {
            get { return !_denyReadData && _allowReadData; }
        }
        public bool CanReadExtendedAttributes
        {
            get { return !_denyReadExtendedAttributes && _allowReadExtendedAttributes; }
        }
        public bool CanReadPermissions
        {
            get { return !_denyReadPermissions && _allowReadPermissions; }
        }
        public bool CanSynchronize
        {
            get { return !_denySynchronize && _allowSynchronize; }
        }
        public bool CanTakeOwnership
        {
            get { return !_denyTakeOwnership && _allowTakeOwnership; }
        }
        public bool CanTraverse
        {
            get { return !_denyTraverse && _allowTraverse; }
        }
        public bool CanWrite
        {
            get { return !_denyWrite && _allowWrite; }
        }
        public bool CanWriteAttributes
        {
            get { return !_denyWriteAttributes && _allowWriteAttributes; }
        }
        public bool CanWriteData
        {
            get { return !_denyWriteData && _allowWriteData; }
        }
        public bool CanWriteExtendedAttributes
        {
            get { return !_denyWriteExtendedAttributes && _allowWriteExtendedAttributes; }
        }

        public FileAccessRigths(string path) : this(path, WindowsIdentity.GetCurrent())
        { 
        
        }

		public FileAccessRigths(string path, System.Security.Principal.WindowsIdentity principal)
        {
			if (string.IsNullOrEmpty(path))
				throw new ArgumentNullException("path");

            _path = path;

            try
            {
                FileInfo fi = new FileInfo(_path);

                AuthorizationRuleCollection acl = fi.GetAccessControl().GetAccessRules(true, true, typeof(SecurityIdentifier));

                foreach (FileSystemAccessRule rule in acl)
                {
                    if (principal.User.Equals(rule.IdentityReference))
                        CheckRule(rule);
                }

                foreach (IdentityReference identityReference in principal.Groups)
                {
                    foreach (FileSystemAccessRule rule in acl)
                    {
                        if (identityReference.Equals(rule.IdentityReference))
                            CheckRule(rule);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void CheckRule(FileSystemAccessRule rule)
        {
            if (AccessControlType.Deny.Equals(rule.AccessControlType))
            {
                if (Contains(FileSystemRights.AppendData, rule)) _denyAppendData = true;
                if (Contains(FileSystemRights.ChangePermissions, rule)) _denyChangePermissions = true;
                if (Contains(FileSystemRights.CreateDirectories, rule)) _denyCreateDirectories = true;
                if (Contains(FileSystemRights.CreateFiles, rule)) _denyCreateFiles = true;
                if (Contains(FileSystemRights.Delete, rule)) _denyDelete = true;
                if (Contains(FileSystemRights.DeleteSubdirectoriesAndFiles, rule)) _denyDeleteSubdirectoriesAndFiles = true;
                if (Contains(FileSystemRights.ExecuteFile, rule)) _denyExecuteFile = true;
                if (Contains(FileSystemRights.FullControl, rule)) _denyFullControl = true;
                if (Contains(FileSystemRights.ListDirectory, rule)) _denyListDirectory = true;
                if (Contains(FileSystemRights.Modify, rule)) _denyModify = true;
                if (Contains(FileSystemRights.Read, rule)) _denyRead = true;
                if (Contains(FileSystemRights.ReadAndExecute, rule)) _denyReadAndExecute = true;
                if (Contains(FileSystemRights.ReadAttributes, rule)) _denyReadAttributes = true;
                if (Contains(FileSystemRights.ReadData, rule)) _denyReadData = true;
                if (Contains(FileSystemRights.ReadExtendedAttributes, rule)) _denyReadExtendedAttributes = true;
                if (Contains(FileSystemRights.ReadPermissions, rule)) _denyReadPermissions = true;
                if (Contains(FileSystemRights.Synchronize, rule)) _denySynchronize = true;
                if (Contains(FileSystemRights.TakeOwnership, rule)) _denyTakeOwnership = true;
                if (Contains(FileSystemRights.Traverse, rule)) _denyTraverse = true;
                if (Contains(FileSystemRights.Write, rule)) _denyWrite = true;
                if (Contains(FileSystemRights.WriteAttributes, rule)) _denyWriteAttributes = true;
                if (Contains(FileSystemRights.WriteData, rule)) _denyWriteData = true;
                if (Contains(FileSystemRights.WriteExtendedAttributes, rule)) _denyWriteExtendedAttributes = true;
            }
            else if (AccessControlType.Allow.Equals(rule.AccessControlType))
            {
                if (Contains(FileSystemRights.AppendData, rule)) _allowAppendData = true;
                if (Contains(FileSystemRights.ChangePermissions, rule)) _allowChangePermissions = true;
                if (Contains(FileSystemRights.CreateDirectories, rule)) _allowCreateDirectories = true;
                if (Contains(FileSystemRights.CreateFiles, rule)) _allowCreateFiles = true;
                if (Contains(FileSystemRights.Delete, rule)) _allowDelete = true;
                if (Contains(FileSystemRights.DeleteSubdirectoriesAndFiles, rule)) _allowDeleteSubdirectoriesAndFiles = true;
                if (Contains(FileSystemRights.ExecuteFile, rule)) _allowExecuteFile = true;
                if (Contains(FileSystemRights.FullControl, rule)) _allowFullControl = true;
                if (Contains(FileSystemRights.ListDirectory, rule)) _allowListDirectory = true;
                if (Contains(FileSystemRights.Modify, rule)) _allowModify = true;
                if (Contains(FileSystemRights.Read, rule)) _allowRead = true;
                if (Contains(FileSystemRights.ReadAndExecute, rule)) _allowReadAndExecute = true;
                if (Contains(FileSystemRights.ReadAttributes, rule)) _allowReadAttributes = true;
                if (Contains(FileSystemRights.ReadData, rule)) _allowReadData = true;
                if (Contains(FileSystemRights.ReadExtendedAttributes, rule)) _allowReadExtendedAttributes = true;
                if (Contains(FileSystemRights.ReadPermissions, rule)) _allowReadPermissions = true;
                if (Contains(FileSystemRights.Synchronize, rule)) _allowSynchronize = true;
                if (Contains(FileSystemRights.TakeOwnership, rule)) _allowTakeOwnership = true;
                if (Contains(FileSystemRights.Traverse, rule)) _allowTraverse = true;
                if (Contains(FileSystemRights.Write, rule)) _allowWrite = true;
                if (Contains(FileSystemRights.WriteAttributes, rule)) _allowWriteAttributes = true;
                if (Contains(FileSystemRights.WriteData, rule)) _allowWriteData = true;
                if (Contains(FileSystemRights.WriteExtendedAttributes, rule)) _allowWriteExtendedAttributes = true;
            }
        }

        public bool Contains(FileSystemRights right, FileSystemAccessRule rule)
        {
            return (((int)right & (int)rule.FileSystemRights) == (int)right);
        }

        public override String ToString()
        {
            StringBuilder str = new StringBuilder();

            if (this.CanAppendData) str.Append("AppendData, ");
            if (this.CanChangePermissions) str.Append("ChangePermissions, ");
            if (this.CanCreateDirectories) str.Append("CreateDirectories, ");
            if (this.CanCreateFiles) str.Append("CreateFiles, ");
            if (this.CanDelete) str.Append("Delete, ");
            if (this.CanDeleteSubdirectoriesAndFiles) str.Append("DeleteSubdirectoriesAndFiles, ");
            if (this.CanExecuteFile) str.Append("ExecuteFile, ");
            if (this.CanFullControl) str.Append("FullControl, ");
            if (this.CanListDirectory) str.Append("ListDirectory, ");
            if (this.CanModify) str.Append("Modify, ");
            if (this.CanRead) str.Append("Read, ");
            if (this.CanReadAndExecute) str.Append("ReadAndExecute, ");
            if (this.CanReadAttributes) str.Append("ReadAttributes, ");
            if (this.CanReadData) str.Append("ReadData, ");
            if (this.CanReadExtendedAttributes) str.Append("ReadExtendedAttributes, ");
            if (this.CanReadPermissions) str.Append("ReadPermissions, ");
            if (this.CanSynchronize) str.Append("Synchronize, ");
            if (this.CanTakeOwnership) str.Append("TakeOwnership, ");
            if (this.CanTraverse) str.Append("Traverse, ");
            if (this.CanWrite) str.Append("Write, ");
            if (this.CanWriteAttributes) str.Append("WriteAttributes, ");
            if (this.CanWriteData) str.Append("WriteData, ");
            if (this.CanWriteExtendedAttributes) str.Append("WriteExtendedAttributes, ");
            
            if (String.IsNullOrEmpty(str.ToString()))
                str.Append("None, ");

            return str.ToString().Substring(0, str.ToString().Length - 2);
        }
	}
}